package com.xuecheng.order.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuecheng.commons.constants.OrdersConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.CoursePubIndexDto;
import com.xuecheng.commons.model.dto.PageRequest;
import com.xuecheng.commons.model.dto.RecordDto;
import com.xuecheng.commons.model.vo.*;
import com.xuecheng.commons.utils.AuthInfoHolder;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.content.api.ContentClient;
import com.xuecheng.learning.api.LearningClient;
import com.xuecheng.order.config.PayTemplate;
import com.xuecheng.order.domain.Orders;
import com.xuecheng.order.domain.Payment;
import com.xuecheng.order.mapper.OrdersMapper;
import com.xuecheng.order.service.OrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.order.service.PaymentService;
import com.xuecheng.search.api.SearchClient;
import com.xuecheng.web.exception.BusinessException;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * <p>
 * 订单 服务实现类
 * </p>
 *
 * @author itheima
 * @since 2022-12-13
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {

    @Autowired
    PayTemplate payTemplate;
    @Autowired
    SearchClient searchClient;

    @Autowired
    PaymentService paymentService;
    @Autowired
    LearningClient learningClient;
    @Override
    public ResponseResult<String> createOrder(Long coursePubId) {
        //获取用户id
        Long userId = AuthInfoHolder.getUserId();
        //判断用户是否购买（600002）
        Long count = this.lambdaQuery()
                .eq(Orders::getCoursePubId, coursePubId)
                .eq(Orders::getUserId, userId)
                .eq(Orders::getStatus, OrdersConstants.ORDER_PAID_STATUS).count();
        if (count > 0) {
            throw new BusinessException(ErrorCode.ORDERERROR);
        }
        //判断用户是否已经下单(600001)
        Orders orders = this.lambdaQuery()
                .eq(Orders::getCoursePubId, coursePubId)
                .eq(Orders::getUserId, userId)
                .eq(Orders::getStatus, OrdersConstants.ORDER_INIT_STATUS).one();
        if (orders != null) {
            return ResponseResult.okResult(orders.getOrderNo());
        }
        //否则就封装订单
        orders = new Orders();
        //查询课程发布对象
        ResponseResult<CoursePubIndexVo> responseResult = searchClient.findById(coursePubId.toString());
        if (responseResult.getCode() != 0) {
            throw new BusinessException(ErrorCode.PAYERROR);
        }
        CoursePubIndexVo pubIndexVo = responseResult.getData();
        //  封装参数
        orders.setOrderNo(IdUtil.simpleUUID()); // 32位UUID
        orders.setCoursePubId(pubIndexVo.getCourseId());// 课程id
        orders.setCoursePubName(pubIndexVo.getName());// 课程名称
        orders.setCompanyId(pubIndexVo.getCompanyId()); // 机构id
        orders.setCompanyName(pubIndexVo.getCompanyName());// 机构名称
        orders.setUserId(userId);// 用户id
        orders.setPrice(pubIndexVo.getPrice().longValue());// 订单价格，单位分
        orders.setStatus(OrdersConstants.ORDER_INIT_STATUS); // 订单状态未支付
        orders.setCreateDate(new Date()); // 下单时间
        // 5.保存订单
        this.save(orders);
        // 6.返回订单号
        return ResponseResult.okResult(orders.getOrderNo());
    }

    @Override
    @GlobalTransactional
    public ResponseResult<OrdersVo> isPay(String orderNo) {
        //查询微信支付状态
        Boolean checkPayment = payTemplate.checkPayment(orderNo);
        if (checkPayment == false) {
            throw new BusinessException(ErrorCode.NOTPLAY);
        }
        //如果已支付
        //查询订单
        Orders orders = this.lambdaQuery()
                .eq(Orders::getOrderNo, orderNo)
                .one();
        //判断订单状态
        if (orders.getStatus().equals(OrdersConstants.ORDER_INIT_STATUS)) {
            //调用抽取的更新方法更新订单，明细，选课记录
            updatePayStatus(orderNo,orders);
        }
        //订单转vo
        OrdersVo vo = BeanHelper.copyProperties(orders, OrdersVo.class);
        //返回vo
        return ResponseResult.okResult(vo);
    }

    // 查询未支付订单，清理
    @Override
    public void clearOrder() {
        // 1.查询15分钟前未支付订单
        // 1-1 获得前15分钟时间
        Date date = DateUtil.offsetMinute(new Date(), -15).toJdkDate();// 9:46 - 15 = 9:31
        // 1-2 查询数据库
        List<Orders> ordersList = this.lambdaQuery()
                .lt(Orders::getCreateDate, date)
                .eq(Orders::getStatus, OrdersConstants.ORDER_INIT_STATUS)
                .list();
        // 2.遍历再次查询微信，是否支付
        if (CollectionUtil.isNotEmpty(ordersList)) {
            for (Orders orders : ordersList) {
                // 3.查询微信是否付款 二次校验
                Boolean isPay = payTemplate.checkPayment(orders.getOrderNo());
                if (isPay==true) { // 用户已付款
                    // 更新订单、明细状态，保存选课记录
                    updatePayStatus(orders.getOrderNo(),orders);
                }else{ // 用户未付款
                    // 微信关闭订单
                    payTemplate.closeOrder(orders.getOrderNo());
                    // 数据库关闭订单
                    orders.setStatus(OrdersConstants.ORDER_CLOSED_STATUS);
                    this.updateById(orders);
                }
            }
        }else{
            System.out.println("没有超时订单...");
        }
    }

    @Autowired
    ContentClient contentClient;
    //用户课程订单列表
    @Override
    public ResponseResult<PersonOrdersVo> findOrdersByPage(PageRequest pageRequest) {
        //获取参数
        Integer pageNo = pageRequest.getPageNo();
        Integer pageSize = pageRequest.getPageSize();
        //链式编程查询数据
        Page<Orders> page = new Page<>(pageNo,pageSize);
        page = this.lambdaQuery().eq(Orders::getUserId,AuthInfoHolder.getUserId()).page(page);
        //判断查询结果为空
        if (CollectionUtil.isEmpty(page.getRecords())) {
            throw new BusinessException(ErrorCode.NOTFOUND);
        }
        //数据不为空
        //获取总记录数
        long total = page.getTotal();
        //将entiy转vo
        List<PersonOrdersVo> list = BeanHelper.copyWithCollection(page.getRecords(), PersonOrdersVo.class);
        for (PersonOrdersVo ordersVo : list) {
            //查询课程发布对象
            ResponseResult<CoursePubVo> responseResult = contentClient.findById(ordersVo.getCoursePubId());
            if (responseResult.getCode() != 0) {
                throw new BusinessException(ErrorCode.PAYERROR);
            }
            CoursePubVo pubVo = responseResult.getData();
            //补全课程图片
            ordersVo.setContentImage(pubVo.getPic());
        }
        //返回数据
        return PageResponseResult.okResult(total,list);

    }

    //更新订单状态
    private void updatePayStatus(String orderNo, Orders orders) {
        //更新订单
        orders.setStatus(OrdersConstants.ORDER_PAID_STATUS);
        this.updateById(orders);
        //更新订单明细
        paymentService.lambdaUpdate()
                .set(Payment::getStatus,1)
                .eq(Payment::getOrderNo,orderNo)
                .update();
        //保存选课记录
        RecordDto recordDto = new RecordDto();
        recordDto.setUserId(orders.getUserId()); // 用户id
        recordDto.setCoursePubId(orders.getCoursePubId()); // 课程id
        ResponseResult responseResult = learningClient.saveRecord(recordDto);
        //全局事务管理方案一
        //if (responseResult.getCode() != 0) {
        //    throw new BusinessException(ErrorCode.PARAMSERROR);
        //}
    }
}
